\section{Diseño Orientado a Objetos}


Cuando se comenzó con el diseño de clases necesario para el desarrollo de este proyecto, se optó por darle prioridad a los diagramas de secuencias. Entendimos que esa clase de diagramas, nos ayudaban a empezar a comprender a grandes razgos cómo iban a ser las interacciones, qué objetos clases podíamos necesitar y qué objetos participaban en cada uno de los escenarios posibles.


Al mismo tiempo, se fueron esbozando diagramas de objetos y de clases que nos ayudaran a comprender más detalladamente las distintas relaciones entre los objetos y las clases, qué objetos se comportaban de forma similar a otros, qué responsabilidades tenía cada objeto, entre otras. De esta manera, se logró tener una comprensión general de cómo podía funcionar el sistema.


A partir de entonces, el grupo utilizó la técnica de Test Driven Development (TDD) en conjunto con las herramientas de diseño antes mencionadas para poder avanzar con el diseño al mismo tiempo que se avanzaba con el desarrollo, permitiendo encontrar tempranamente errores de comportamiento y de diseño.


Como se comentó anteriormente, en el comienzo del diseño nos resultó más natural encarar el análisis del problema a través de los diagramas de secuencias. Esto nos permitió por ejemplo, poder comprender mejor el entorno del problema, pudiendo nombrar a las clases de forma que reflejaran lo mejor posible la realidad. Gracias a ello, surgieron nombres de clases como ``Fiscal'', ``CuartoOscuro'', ``Voto'', ``RegistradorDeCandidatos'', entre otros. 

A continuación, se presenta el diagrama de clases que fue implementado en esta primer iteración:


\begin{figure}[!h]
  \centering
  \includegraphics[scale=0.5,angle=90]{./otros/Vox/diagrama_de_clases.jpeg}
\end{figure}


\subsection{Explicación de las clases utilizadas}

Una de las clases que surgió naturalmente fue la clase ``Fiscal''. Utilizando nuestro conocimiento previo sobre lo relacionado a una elección y lo descripto en el enunciado de este trabajo práctico, nos encontramos con la necesidad de tener una entidad que tuviera la responsabilidad de corroborar que la persona que se presentara a votar, fuese un votante legítimo. Esto significa que debía verificar en algún listado similar a un padrón, si los datos de la persona que pretendía votar eran válidos. Esto definitivamente es responsabilidad de un fiscal. Por este motivo, es que la clase ``Fiscal'' sabe responder al mensaje ``autenticar''. Lo mismo sucede una vez que el votante desea emitir su voto. El fiscal es el encargado de anotar que esa persona emitió su voto y de indicarle donde colocar su boleta. Finalmente, la última responsabilidad que le atribuímos al fiscal es la de poder cerrar una elección. Nuevamente, suena razonable que un fiscal sea el encargado de esta tarea.

Más adelante y continuando con esta forma de pensar y analizar los escenarios, notamos que era necesario tener una clase que representara a un cuarto oscuro de una elección. Entre sus responsabilidades tiene la de dar a conocer el listado de candidatos disponibles. La analogía de esta responsabilidad con la realidad es que dentro del cuarto oscuro uno puede encontrar las distintas boletas de los candidatos. Sin embargo, en este caso hubo que considerar otras cuestiones. Cada claustro de la facultad tenía sus candidatos. Por lo tanto, era correcto pensar que cuando un votante le enviara el mensaje ``candidatos'' a un cuarto oscuro, este le permita ver solo aquellos candidatos del mismo claustro del votante en cuestión. Como el fiscal a priori no conoce el claustro de un votante hasta que este se loguea, se concluyó que era una buena idea utilizar un patrón de diseño similar al Factory para sortear este problema. De esta manera, cuando un usuario se logueaba, el fiscal colaboraba con el ``CuartoOscuroFactory'' enviandole el claustro al cuál pertenecía el usuario, de manera que el ``CuartoOscuroFactory'' supiera qué tipo de cuarto oscuro se estaba necesitando. Además, el cuarto oscuro sabía responder el mensaje ``votar\_a'', el cuál devolvía un objeto de la clase ``Voto''. Esto podría compararse con el hecho de tomar una boleta de un candidato en la realidad e ingresarla en un sobre.


Algo similar sucedió a la hora de tener que registrar a los candidatos. La tarea de registrar a un candidato para la elección fue designada a un objeto de la clase ``RegistradorDeCandidatos''. Como no había forma de saber de antemano en qué claustro quería presentarse como candidato el visitante de la página web, se debió implementar un ``RegistradorDeCandidatosFactory'', el cuál creaba ``RegistradorDeCandidatosDocentes'',``RegistradorDeCandidatosAlumnos'' y ``RegistradorDeCandidatosGraduados'' según correspondiera. La tarea de un registrador era registrar a una persona como candidato, siempre y cuando la misma cumpliera con ciertos requisitos, los cuales estaban escritos en un reglamento. Tanto del enunciado del trabajo práctico, como de nuestro análisis, como de las entrevistas con el cliente, notamos que este reglamento podía no ser algo fijo y que podría llegar a cambiar el alguna ocasión. Por este motivo, se optó por representar a un reglamento como utilizando un patrón de diseño similar al de un ``Strategy''. Esto nos permitía poder cambiar de reglamento sin necesidad de realizar cambios estructurales en nuestro código.


Esta interacción/relación entre un registrador y un reglamento es similar a la que se dió entre los objetos de la clase ``ProcesadorDeResultados'' y ``AlgoritmoDeGanadoresActual''. El procesador básicamente siempre hace lo mismo (contar votos), pero las reglas que aplican para el cálculo de los ganadores de una elección varían en el tiempo. No sólo eso, sino que además son las que indican qué hacer en caso que el conteo de votos tenga conflictos, como por ejemplo, empate de los primeros candidatos en cantidad de votos, que no se cubra la cantidad mínima de miembros de un claustro necesarios para participar del CoDep, entre otras. Por eso es que para este caso también, se optó por seguir en patrón de diseño ``Strategy''.


Finalmente, parte del desarrollo necesitaba de la comunicación de VOX con un sistema externo que nos proveyera ciertos datos relevantes a la hora de validar distintos atributos de los votantes y de los candidatos que requerían darse de alta. En este caso, no había ninguna especificación de cómo iba a ser esa comunicación entre los dos sistemas, y tampoco era algo que a priori supiera el cliente, por lo que se evitó inferir una interfaz de comunicación con el sistema externo. No sólo porque no había información al respecto, sino también porque al no conocer las bondades del sistema externo, cualquier comportamiento que asumieramos válido iba a obligarnos después a modificar el código en caso que el sistema externo no se comportara como esperábamos. Por estos motivos, se decidió que lo más indicado era modelar esta interacción utilizando el patrón de diseño conocido como ``Adapter''. Esto nos permite crear una especie de interfaz entre nuestro sistema y el sistema externo de forma que si en algún momento debemos cambiar esa interacción, sólo haya que modificar el código del adapter (clase intermedia) y no la de nuestro sistema.

\textbf{Aclaración: } Durante el desarrollo del trabajo práctico, nos encontramos con que era correcto que alguna de las clases antes mencionadas se correspondieran con el patrón de diseño ``Singleton''. En el código, se puede ver que una de ellas fue implementada por el grupo. Como para el resto de las clases con el mismo patrón había que hacer lo mismo, se decidió utilizar una herramienta de Ruby que siguiera este patrón y nos ahorrara tener que repetir ese comportamiento.

\input{escenarios_y_diag_de_secuencias.tex}
